导航菜单
首页 >  FLask之Local、LocalStack和LocalProxy介绍  > flask 中的 werkzeug Local,LocalStack 和 LocalProxy 技术应用

flask 中的 werkzeug Local,LocalStack 和 LocalProxy 技术应用

什么是 Localwsgi 每次请求,会把过程进行抽离无状态话,过程数据存储在本次请求的全局变量中,使用到了Local. Local 作为每次请求的全局命令空间,属于每次请求的私有LocalStack 与 Local 相似,在 Local 基础之上使用堆栈方式进行操作,管理LocalProxy 代理类,代理 Local 或 LocalStack 实例为什么使用 Local

为什么使用自定义 Local,而不是 threading.local。这是由内核决定的

1. web 应用在启动之后,是一单线+协成程启动的话,会污染全局变量,无法区分,

2. 使用多线程+协成无法保证,派发请求的工作协程,无法保证同时工作时且分别位于多个线程内,彼此互不影响

所以: werkzeug 给出了自己的解决方案:Local 和 LocalStack

为什么使用 LocalProxy

那么问题来了:请求的上下文的私有变量存储在 Local 和 LocalStack 中,那在多任务时,每次调用 from flask import request, g, session , 如何保证获取正确的上下文,而不发生混乱?

在 flask.globals.py 中

def _lookup_req_object(name): top = _request_ctx_stack.top if top is None: raise RuntimeError('working outside of request context') return getattr(top, name) _request_ctx_stack = LocalStack() request = LocalProxy(partial(_lookup_req_object, 'request')) session = LocalProxy(partial(_lookup_req_object, 'session'))

 

在 werkzeug.local.py 中, LocalProxy是一个 Local or LocalStack 的一个代理

@implements_boolclass LocalProxy(object): """"""__slots__ = ("__local", "__dict__", "__name__", "__wrapped__")def __init__(self, local, name=None):object.__setattr__(self, "_LocalProxy__local", local) object.__setattr__(self, "__name__", name) if callable(local) and not hasattr(local, "__release_local__"): # "local" is a callable that is not an instance of Local or # LocalManager: mark it as a wrapped function. object.__setattr__(self, "__wrapped__", local)def _get_current_object(self): """Return the current object. This is useful if you want the real object behind the proxy at a time for performance reasons or because you want to pass the object into a different context. """ if not hasattr(self.__local, "__release_local__"): return self.__local() try: return getattr(self.__local, self.__name__) except AttributeError: raise RuntimeError("no object bound to %s" % self.__name__) def __getattr__(self, name): if name == "__members__": return dir(self._get_current_object()) return getattr(self._get_current_object(), name)

调用 reqeust:动态 request

相关推荐: